package com.wct.genetic;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * @author WEI
 * @date 2018/5/27 13:48
 */
public class MatrixTool {

    public static final int[][] DIS_MATRIX = {
            {0, 31, 54, 53, 56, 34, 15, 50, 52, 2, 67, 23, 7, 86, 65, 18, 77, 3, 74, 1, 74, 69, 39, 83, 30, 80, 28, 60, 68, 20},
            {31, 0, 25, 87, 65, 91, 71, 46, 10, 25, 38, 95, 86, 78, 61, 33, 83, 73, 8, 8, 5, 36, 23, 75, 13, 13, 7, 18, 94, 80},
            {54, 25, 0, 7, 33, 20, 75, 76, 89, 50, 12, 12, 30, 5, 41, 82, 30, 72, 14, 61, 97, 96, 81, 92, 41, 94, 2, 53, 34, 30},
            {53, 87, 7, 0, 8, 100, 1, 38, 96, 23, 100, 75, 15, 50, 68, 18, 40, 89, 100, 60, 9, 98, 31, 71, 12, 34, 2, 16, 90, 54},
            {56, 65, 33, 8, 0, 8, 10, 49, 61, 97, 79, 52, 18, 65, 42, 68, 57, 95, 89, 27, 52, 82, 26, 52, 11, 58, 61, 67, 1, 28},
            {34, 91, 20, 100, 8, 0, 26, 12, 45, 29, 93, 24, 64, 99, 54, 93, 47, 83, 22, 54, 23, 49, 43, 12, 96, 45, 52, 50, 88, 43},
            {15, 71, 75, 1, 10, 26, 0, 26, 21, 72, 24, 79, 48, 40, 87, 88, 16, 49, 68, 54, 35, 11, 94, 1, 69, 57, 75, 50, 59, 81},
            {50, 46, 76, 38, 49, 12, 26, 0, 72, 21, 60, 3, 42, 48, 50, 9, 66, 99, 66, 37, 92, 78, 24, 28, 2, 63, 78, 69, 86, 56},
            {52, 10, 89, 96, 61, 45, 21, 72, 0, 32, 57, 5, 69, 36, 58, 27, 82, 71, 42, 27, 36, 58, 8, 92, 100, 87, 36, 94, 16, 16},
            {2, 25, 50, 23, 97, 29, 72, 21, 32, 0, 83, 33, 65, 49, 41, 80, 39, 14, 80, 60, 46, 71, 71, 59, 31, 100, 55, 89, 20, 87},
            {67, 38, 12, 100, 79, 93, 24, 60, 57, 83, 0, 72, 6, 10, 47, 60, 27, 61, 99, 42, 60, 26, 12, 66, 95, 48, 46, 89, 86, 40},
            {23, 95, 12, 75, 52, 24, 79, 3, 5, 33, 72, 0, 47, 70, 92, 22, 52, 76, 36, 19, 3, 67, 10, 93, 58, 83, 57, 50, 12, 13},
            {7, 86, 30, 15, 18, 64, 48, 42, 69, 65, 6, 47, 0, 77, 42, 54, 93, 92, 45, 99, 31, 67, 68, 84, 28, 29, 5, 68, 48, 9},
            {86, 78, 5, 50, 65, 99, 40, 48, 36, 49, 10, 70, 77, 0, 26, 57, 64, 1, 54, 6, 12, 63, 11, 84, 43, 61, 39, 17, 34, 32},
            {65, 61, 41, 68, 42, 54, 87, 50, 58, 41, 47, 92, 42, 26, 0, 47, 84, 97, 95, 73, 70, 57, 36, 82, 34, 29, 15, 42, 39, 69},
            {18, 33, 82, 18, 68, 93, 88, 9, 27, 80, 60, 22, 54, 57, 47, 0, 12, 73, 49, 13, 33, 19, 93, 59, 34, 98, 78, 19, 25, 40},
            {77, 83, 30, 40, 57, 47, 16, 66, 82, 39, 27, 52, 93, 64, 84, 12, 0, 4, 58, 83, 7, 68, 18, 74, 31, 18, 8, 86, 43, 35},
            {3, 73, 72, 89, 95, 83, 49, 99, 71, 14, 61, 76, 92, 1, 97, 73, 4, 0, 94, 79, 39, 60, 73, 98, 44, 44, 93, 90, 43, 59},
            {74, 8, 14, 100, 89, 22, 68, 66, 42, 80, 99, 36, 45, 54, 95, 49, 58, 94, 0, 28, 49, 58, 42, 76, 46, 43, 40, 79, 68, 91},
            {1, 8, 61, 60, 27, 54, 54, 37, 27, 60, 42, 19, 99, 6, 73, 13, 83, 79, 28, 0, 48, 79, 13, 48, 42, 6, 76, 39, 26, 20},
            {74, 5, 97, 9, 52, 23, 35, 92, 36, 46, 60, 3, 31, 12, 70, 33, 7, 39, 49, 48, 0, 88, 16, 80, 65, 74, 74, 46, 46, 75},
            {69, 36, 96, 98, 82, 49, 11, 78, 58, 71, 26, 67, 67, 63, 57, 19, 68, 60, 58, 79, 88, 0, 65, 97, 9, 83, 80, 31, 96, 81},
            {39, 23, 81, 31, 26, 43, 94, 24, 8, 71, 12, 10, 68, 11, 36, 93, 18, 73, 42, 13, 16, 65, 0, 69, 10, 53, 55, 59, 6, 27},
            {83, 75, 92, 71, 52, 12, 1, 28, 92, 59, 66, 93, 84, 84, 82, 59, 74, 98, 76, 48, 80, 97, 69, 0, 18, 10, 4, 94, 84, 96},
            {30, 13, 41, 12, 11, 96, 69, 2, 100, 31, 95, 58, 28, 43, 34, 34, 31, 44, 46, 42, 65, 9, 10, 18, 0, 11, 89, 91, 10, 20},
            {80, 13, 94, 34, 58, 45, 57, 63, 87, 100, 48, 83, 29, 61, 29, 98, 18, 44, 43, 6, 74, 83, 53, 10, 11, 0, 86, 11, 42, 49},
            {28, 7, 2, 2, 61, 52, 75, 78, 36, 55, 46, 57, 5, 39, 15, 78, 8, 93, 40, 76, 74, 80, 55, 4, 89, 86, 0, 8, 37, 79},
            {60, 18, 53, 16, 67, 50, 50, 69, 94, 89, 89, 50, 68, 17, 42, 19, 86, 90, 79, 39, 46, 31, 59, 94, 91, 11, 8, 0, 48, 97},
            {68, 94, 34, 90, 1, 88, 59, 86, 16, 20, 86, 12, 48, 34, 39, 25, 43, 43, 68, 26, 46, 96, 6, 84, 10, 42, 37, 48, 0, 38},
            {20, 80, 30, 54, 28, 43, 81, 56, 16, 87, 40, 13, 9, 32, 69, 40, 35, 59, 91, 20, 75, 81, 27, 96, 20, 49, 79, 97, 38, 0}
    };

    /**
     * 鐢熸垚涓�釜瀵圭О鐭╅樀
     *
     * @param length 琛屾暟
     * @return 浜岀淮鏁扮粍锛屼竴涓绉扮煩闃�
     */
    public static int[][] initMatrix(int length, int maxDistance) {
        //鍒濆鍖栬窛绂荤煩闃碉紝璺濈闅忔満鐢熸垚
        if (length <= 0 || maxDistance < 0) {
            throw new RuntimeException("Can't generate an array,because length is <=0");
        }
        //璺濈鐭╅樀
        int[][] matrix = new int[length][length];
        //鐢熸垚闅忔満鏁�
        Random random = new Random(System.currentTimeMillis());
        int number;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                if (i == j) {
                    matrix[i][j] = 0;
                } else {
                    number = random.nextInt(maxDistance) + 1;
                    //缁欏绉扮煩闃佃祴鍊�
                    matrix[i][j] = number;
                    matrix[j][i] = number;
                }
            }
        }
        return matrix;
    }

    /**
     * 瀵瑰绉扮煩闃佃繘琛屽帇缂�
     *
     * @param matrix 涓�釜浜岀淮鏁扮粍
     * @return 鍘嬬缉鍚庣殑涓�淮鏁扮粍
     */
    public static int[] compressMatrix(int[][] matrix) {
        if (matrix == null) {
            throw new NullPointerException("Matrix is null");
        }
        //琛屾暟=鍒楁暟=matrix.length
        int row = matrix.length;
        //涓嬩笁瑙掓湁 n*(n+1)/2 涓厓绱�
        int[] compressionMatrix = new int[row * (row + 1) / 2];
        //鏁扮粍绱㈠紩
        int index;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j <= i; j++) {
                // Aij = SA[k],k = (i+1)*i/2+ j.(鐭╅樀浠庣0琛屽紑濮嬫暟)
                // Aij = SA[k],k = i*(i-1)/2+ j-1.(鐭╅樀浠庣1琛屽紑濮嬫暟)
                index = (i + 1) * i / 2 + j;
                compressionMatrix[index] = matrix[i][j];
            }
        }
        return compressionMatrix;
    }

    /**
     * 閬嶅巻浜岀淮鏁扮粍
     *
     * @param matrix 浜岀淮鏁扮粍
     */
    public static void printMatrix(int[][] matrix) {
        if (matrix == null) {
            throw new NullPointerException("Matrix is null");
        }
        //閬嶅巻瀵圭О鐭╅樀
        for (int[] aMatrix : matrix) {
            System.out.print("{");
            for (int item : aMatrix) {
                System.out.print(item + ",");
            }
            System.out.println("},");
        }
    }

    public static void printMatrix(double[][] matrix) {
        if (matrix == null) {
            throw new NullPointerException("Matrix is null");
        }
        for (double[] aMatrix : matrix) {
            System.out.print("{");
            for (double item : aMatrix) {
                System.out.print(item + ",");
            }
            System.out.println("},");
        }
    }

    /**
     * 閬嶅巻涓�淮鏁扮粍
     *
     * @param compressionMatrix 鍘嬬缉鍚庣殑璺濈鐭╅樀
     */
    public static void printCompressionMatrix(int[] compressionMatrix) {
        if (compressionMatrix == null) {
            throw new NullPointerException("Matrix is null");
        }
        //閬嶅巻瀵圭О鐭╅樀
        for (int item : compressionMatrix) {
            System.out.print(item + " ");
        }
        System.out.println();
    }

    public static Map<String, Integer> saveDistanceToMap(String[] cityName, int[][] distanceMatrix) {
        Map<String, Integer> distanceMap = new HashMap<String,Integer>(cityName.length * cityName.length);
        //
        for (int i = 0; i < distanceMatrix.length; i++) {
            for (int j = 0; j <= i; j++) {
                distanceMap.put(cityName[i] + cityName[j], distanceMatrix[i][j]);
                distanceMap.put(cityName[j] + cityName[i], distanceMatrix[i][j]);
            }
        }
        return distanceMap;
    }
}
